// Copyright (c) 2008-2010, Arne Claus
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 
// following conditions are met:
//
// - Redistributions of source code must retain the above copyright notice, this list of conditions and the following 
//   disclaimer.
// - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 
//   disclaimer in the documentation and/or other materials provided with the distribution.
// - Neither the name Arne Claus nor the names of any contributors may be used to endorse or promote products
//   derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef __INCLUDED_CBL_SIMPLE_INTRUSIVE_LIST_H__
#define __INCLUDED_CBL_SIMPLE_INTRUSIVE_LIST_H__

#include "CBL_Defines.h"

CB_NAMESPACE_START

// -------------------------------------------------------------------------------------
//	CSimpleIntrusiveList
//	This is a much more lightweight implementation of CIntrusiveList but on the
//	downside it's much more unsafe:
//	- You will not be able to ask an item what list it is in
//	- Prev and Next pointer will not be NULL after remove
//	- Double insert or remove will not work
//	- Deleting an item will not remove it from the list it is in
//	- Deleting an item from a list it is not in can lead to unexpected results
//	- There is no Size() functionality
//	- Insert cannot be used instead of PushBack
// -------------------------------------------------------------------------------------

template <typename TItemClass, uint32 TListId=0>
class CSimpleIntrusiveList
{
public:
	
	// -------------------------------------------------------------------------------------
	//	CItem
	//	Defines a baseclass for classes that need to be stored inside an intrusive List.
	// -------------------------------------------------------------------------------------
	
	class CItem
	{
	private:
    	friend class CSimpleIntrusiveList;
        
		CItem* m_pIntrusiveListPrev;
		CItem* m_pIntrusiveListNext;
	};
	
public:
	
	CSimpleIntrusiveList();
	~CSimpleIntrusiveList();
	
	void PushBack(CItem& _rItem);
	void PushFront(CItem& _rItem);
	void Insert(CItem& _rItem, CItem& _rNewNext);
	
	void Remove(CItem& _rItem);
	CItem* PopFront();
	CItem* PopBack();
	void Clear();
	
public:
	
	bool IsEmpty();
	
public:
	
	// -------------------------------------------------------------------------------------
	//	CIterator
	//	Wrapper for CItem to support iterator functionality (increment, decrement, etc.)
	// -------------------------------------------------------------------------------------
	
	class CIterator
	{
	public:
		
		CIterator(CItem* _pItem) : m_pCurrent(_pItem) {}
		
		CIterator operator ++ (int)					{ CItem* pLast = m_pCurrent; ++(*this); return CIterator(pLast); }
		void operator ++ ()							{ m_pCurrent = m_pCurrent->m_pIntrusiveListNext; }
		
		CIterator operator -- (int)					{ CItem* pLast = m_pCurrent; --(*this); return CIterator(pLast); }
		void operator -- ()							{ m_pCurrent = m_pCurrent->m_pIntrusiveListPrev; }
		
		CIterator& operator += (int _Count);
		CIterator operator + (int _Count);
		
		TItemClass& operator * ()					{ return *static_cast<TItemClass*>(m_pCurrent); }
		TItemClass* operator -> ()					{ return static_cast<TItemClass*>(m_pCurrent); }
		
		bool IsValid()								{ return m_pCurrent != NULL; }
		
		bool operator == (const CIterator& _rRhs)	{ return m_pCurrent == _rRhs.m_pCurrent; }
		bool operator != (const CIterator& _rRhs)	{ return m_pCurrent != _rRhs.m_pCurrent; }
		
	private:
		
		CItem* m_pCurrent;
	};
	
public:
	
	CIterator Begin();
	CIterator End();
	CIterator RBegin();	
	
private:
	
	CItem* m_pFirst;
	CItem* m_pLast;
};

// -------------------------------------------------------------------------------------
//	Implementation
// -------------------------------------------------------------------------------------

#include "CBL_SimpleIntrusiveList.hpp"

CB_NAMESPACE_END

#endif